#include <thread>
#include <iostream>
#include <mutex>

class some_big_object {
public:
    int a;
};

void swap(some_big_object& lhs, some_big_object& rhs) 
{
    some_big_object t = lhs;
    lhs = rhs;
    rhs = t;
}

class X {
private:
    some_big_object some_detail;
    std::mutex m;
public:
    X(some_big_object const& sd): some_detail(sd) { }
    friend void swap(X& lhs, X&rhs) {
        if (&lhs == &rhs) {
            return;
        }
        std::lock(lhs.m, rhs.m);
        std::lock_guard<std::mutex> lock_a(lhs.m, std::adopt_lock);
        std::lock_guard<std::mutex> lock_b(rhs.m, std::adopt_lock);
        swap(lhs.some_detail, rhs.some_detail);
    }
};

void testSwap() {
    some_big_object s1, s2;
    s1.a = 3;
    s2.a = 4;

    std::cout << "s1.a:" << s1.a << ", s2.a:" << s2.a << std::endl;
    swap(s1, s2);
    std::cout << "s1.a:" << s1.a << ", s2.a:" << s2.a << std::endl;
}

int main(int argc, char const *argv[])
{
    testSwap();
    return 0;
}


